<!--
Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.

This file provided by Facebook is for non-commercial testing and evaluation
purposes only. Facebook reserves all rights not expressly granted.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Draft • Entity Editor</title>
    <link rel="stylesheet" href="../../../dist/Draft.css" />
  </head>
  <body>
    <div id="target"></div>
    <script src="../../../node_modules/react/umd/react.development.js"></script>
    <script src="../../../node_modules/react-dom/umd/react-dom.development.js"></script>
    <script src="../../../node_modules/immutable/dist/immutable.js"></script>
    <script src="../../../node_modules/es6-shim/es6-shim.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.js"></script>
    <script src="../../../dist/Draft.js"></script>
    <script type="text/babel">
      'use strict';

      const {
        convertFromRaw,
        convertToRaw,
        CompositeDecorator,
        Editor,
        EditorState,
      } = Draft;

      const rawContent = {
        blocks: [
          {
            text: (
              'This is an "immutable" entity: Superman. Deleting any ' +
              'characters will delete the entire entity. Adding characters ' +
              'will remove the entity from the range.'
            ),
            type: 'unstyled',
            entityRanges: [{offset: 31, length: 8, key: 'first'}],
          },
          {
            text: '',
            type: 'unstyled',
          },
          {
            text: (
              'This is a "mutable" entity: Batman. Characters may be added ' +
              'and removed.'
            ),
            type: 'unstyled',
            entityRanges: [{offset: 28, length: 6, key: 'second'}],
          },
          {
            text: '',
            type: 'unstyled',
          },
          {
            text: (
              'This is a "segmented" entity: Green Lantern. Deleting any ' +
              'characters will delete the current "segment" from the range. ' +
              'Adding characters will remove the entire entity from the range.'
            ),
            type: 'unstyled',
            entityRanges: [{offset: 30, length: 13, key: 'third'}],
          },
        ],

        entityMap: {
          first: {
            type: 'TOKEN',
            mutability: 'IMMUTABLE',
          },
          second: {
            type: 'TOKEN',
            mutability: 'MUTABLE',
          },
          third: {
            type: 'TOKEN',
            mutability: 'SEGMENTED',
          },
        },
      };

      class EntityEditorExample extends React.Component {
        constructor(props) {
          super(props);

          const decorator = new CompositeDecorator([
            {
              strategy: getEntityStrategy('IMMUTABLE'),
              component: TokenSpan,
            },
            {
              strategy: getEntityStrategy('MUTABLE'),
              component: TokenSpan,
            },
            {
              strategy: getEntityStrategy('SEGMENTED'),
              component: TokenSpan,
            },
          ]);

          const blocks = convertFromRaw(rawContent);

          this.state = {
            editorState: EditorState.createWithContent(blocks, decorator),
          };

          this.focus = () => this.refs.editor.focus();
          this.onChange = (editorState) => this.setState({editorState});
          this.logState = () => {
            const content = this.state.editorState.getCurrentContent();
            console.log(convertToRaw(content));
          };
        }

        render() {
          return (
            <div style={styles.root}>
              <div style={styles.editor} onClick={this.focus}>
                <Editor
                  editorState={this.state.editorState}
                  onChange={this.onChange}
                  placeholder="Enter some text..."
                  ref="editor"
                />
              </div>
              <input
                onClick={this.logState}
                style={styles.button}
                type="button"
                value="Log State"
              />
            </div>
          );
        }
      }

      function getEntityStrategy(mutability) {
        return function(contentBlock, callback, contentState) {
          contentBlock.findEntityRanges(
            (character) => {
              const entityKey = character.getEntity();
              if (entityKey === null) {
                return false;
              }
              return contentState.getEntity(entityKey).getMutability() === mutability;
            },
            callback
          );
        };
      }

      function getDecoratedStyle(mutability) {
        switch (mutability) {
          case 'IMMUTABLE': return styles.immutable;
          case 'MUTABLE': return styles.mutable;
          case 'SEGMENTED': return styles.segmented;
          default: return null;
        }
      }

      const TokenSpan = (props) => {
        const style = getDecoratedStyle(
          props.contentState.getEntity(props.entityKey).getMutability()
        );
        return (
          <span data-offset-key={props.offsetkey} style={style}>
            {props.children}
          </span>
        );
      };

      const styles = {
        root: {
          fontFamily: '\'Helvetica\', sans-serif',
          padding: 20,
          width: 600,
        },
        editor: {
          border: '1px solid #ccc',
          cursor: 'text',
          minHeight: 80,
          padding: 10,
        },
        button: {
          marginTop: 10,
          textAlign: 'center',
        },
        immutable: {
          backgroundColor: 'rgba(0, 0, 0, 0.2)',
          padding: '2px 0',
        },
        mutable: {
          backgroundColor: 'rgba(204, 204, 255, 1.0)',
          padding: '2px 0',
        },
        segmented: {
          backgroundColor: 'rgba(248, 222, 126, 1.0)',
          padding: '2px 0',
        },
      };

      ReactDOM.render(
        <EntityEditorExample />,
        document.getElementById('target')
      );
    </script>
  </body>
</html>
